package com.ruicar.afs.cloud.admin.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruicar.afs.cloud.admin.api.enums.ChangeType;
import com.ruicar.afs.cloud.admin.api.event.AfsRoleChangeEventTrigger;
import com.ruicar.afs.cloud.admin.api.event.RoleChangeEventParam;
import com.ruicar.afs.cloud.admin.dto.RoleDto;
import com.ruicar.afs.cloud.admin.entity.SysUserRole;
import com.ruicar.afs.cloud.admin.service.*;
import com.ruicar.afs.cloud.common.core.log.annotation.SysLog;
import com.ruicar.afs.cloud.admin.entity.SysRole;
import com.ruicar.afs.cloud.admin.entity.SysRoleDataScope;
import com.ruicar.afs.cloud.admin.entity.SysRolePermission;
import com.ruicar.afs.cloud.admin.condition.RoleCondition;
import com.ruicar.afs.cloud.common.core.constant.CommonConstants;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.core.security.vo.RoleVo;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.common.data.datasource.enums.DataScopeTypeEnum;
import com.ruicar.afs.cloud.common.event.AfsEventHelper;
import com.ruicar.afs.cloud.common.event.EventType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


/**
 * x
 */
@Slf4j
@RestController
@Api(description = "角色管理接口")
@AllArgsConstructor
@RequestMapping("/role")
public class SysRoleController {

	private SysRoleService sysRoleService;

	private SysDepartmentService sysDepartmentService;

	private SysRolePermissionService sysRolePermissionService;

	private SysRoleDataScopeService sysRoleDataScopeService;
	private SysUserRoleService sysUserRoleService;



	@RequestMapping(value = "/getAllList", method = RequestMethod.GET)
	@ApiOperation(value = "获取全部角色")
	public IResponse<List<SysRole>> roleGetAll() {
		return new IResponse<List<SysRole>>().setData(sysRoleService.list());
	}

	@RequestMapping(value = "/getAllByPage", method = RequestMethod.GET)
	@ApiOperation(value = "分页获取角色")
	public IResponse getRoleByPage(@RequestParam(name = "pageNumber") int pageNumber, @RequestParam(name = "pageSize") int pageSize) {
		IPage<SysRole> list = sysRoleService.page(new Page(pageNumber, pageSize));
		for (SysRole role : list.getRecords()) {
			// 角色拥有权限
			List<SysRolePermission> permissions = sysRolePermissionService.list(Wrappers.<SysRolePermission>query().lambda().eq(SysRolePermission::getRoleId, role.getId()));
			role.setPermissions(permissions);
			role.setDepartments(sysRoleDataScopeService
					.list(Wrappers.<SysRoleDataScope>lambdaQuery().eq(SysRoleDataScope::getRoleId,role.getId()))
					.stream().map(scope->scope.getDeptId()).collect(Collectors.toList()));
		}
		return new IResponse().setData(list);
	}


	@RequestMapping(value = "/editRolePerm", method = RequestMethod.POST)
	@ApiOperation(value = "编辑角色分配菜单权限")
	@SysLog("编辑角色分配菜单权限")
	@Transactional(rollbackFor = Exception.class)
	@CacheEvict(value = CommonConstants.USER_CACHE_KEY_PREFIX, allEntries = true)
	public IResponse<Boolean> editRolePerm(@RequestBody RoleCondition roleCondition) {

		//删除其关联权限
		sysRolePermissionService.remove(Wrappers.<SysRolePermission>update().lambda().eq(SysRolePermission::getRoleId, roleCondition.getRoleId()));
		//分配新权限
		for (String permId : roleCondition.getPermIds()) {
			SysRolePermission rolePermission = new SysRolePermission();
			rolePermission.setRoleId(roleCondition.getRoleId());
			rolePermission.setPermissionId(permId);
			sysRolePermissionService.save(rolePermission);
		}
		return new IResponse<Boolean>().setData(true);
	}

	@RequestMapping(value = "/editRoleDep", method = RequestMethod.POST)
	@ApiOperation(value = "编辑角色分配数据权限")
	@SysLog("编辑角色分配数据权限")
	@Transactional(rollbackFor = Exception.class)
	@CacheEvict(value = CommonConstants.USER_CACHE_KEY_PREFIX, allEntries = true)
	public IResponse<Boolean> editRoleDep(@RequestBody RoleCondition roleCondition) {


		SysRole sysRole = sysRoleService.getById(roleCondition.getRoleId());

		sysRole.setDsType(roleCondition.getDataType().getType());

		sysRoleDataScopeService.remove(Wrappers.<SysRoleDataScope>lambdaUpdate().eq(SysRoleDataScope::getRoleId,roleCondition.getRoleId()));


		if (roleCondition.getDepIds() == null || roleCondition.getDepIds().length == 0) {
			sysRole.setDsScope("");
		} else {
			List<SysRoleDataScope> sysRoleDataScopes = Arrays.stream(roleCondition.getDepIds()).map(deptId->{
				SysRoleDataScope sysRoleDataScope = new SysRoleDataScope();
				sysRoleDataScope.setRoleId(sysRole.getId());
				sysRoleDataScope.setDeptId(deptId);
				return  sysRoleDataScope;
			}).collect(Collectors.toList());

			sysRoleDataScopeService.saveBatch(sysRoleDataScopes);
			if(roleCondition.getDataType() == DataScopeTypeEnum.SELECT_AND_SUB){
				sysRoleDataScopes.forEach(dept->{
					sysRoleDataScopeService.saveBatch(sysDepartmentService
							.findAllSubByParentId(dept.getDeptId()).stream().map(deptInfo->{
						SysRoleDataScope sysRoleDataScope = new SysRoleDataScope();
						sysRoleDataScope.setRoleId(sysRole.getId());
						sysRoleDataScope.setDeptId(deptInfo.getId());
						return  sysRoleDataScope;
					}).collect(Collectors.toList()));
				});
			}
		}
		sysRoleService.updateById(sysRole);
		return new IResponse<Boolean>().setData(true);
	}

	@RequestMapping(value = "/save", method = RequestMethod.POST)
	@ApiOperation(value = "保存数据")
	@SysLog("保存角色数据")
	@Transactional(rollbackFor = Exception.class)
	@CacheEvict(value = CommonConstants.USER_CACHE_KEY_PREFIX, allEntries = true)
	public IResponse<SysRole> save(@RequestBody RoleDto roleDto) {
		sysRoleService.save(roleDto.getRole());
		List<SysUserRole> list = roleDto.getUserIds().stream().map(userId->{
			SysUserRole sysUserRole = new SysUserRole();
			sysUserRole.setUserId(userId);
			sysUserRole.setRoleId(roleDto.getRole().getId());
			return sysUserRole;
		}).collect(Collectors.toList());
		if(list.size()>0) {
			sysUserRoleService.saveBatch(list);
		}
		return new IResponse<SysRole>().setData(roleDto.getRole());
	}

	@RequestMapping(value = "/edit", method = RequestMethod.POST)
	@ApiOperation(value = "更新数据")
	@SysLog("更新角色数据")
	@Transactional(rollbackFor = Exception.class)
	@CacheEvict(value = CommonConstants.USER_CACHE_KEY_PREFIX, allEntries = true)
	public IResponse<SysRole> edit(@RequestBody RoleDto roleDto) {
		sysRoleService.updateById(roleDto.getRole());

		RoleChangeEventParam roleChangeEventParam = new RoleChangeEventParam();
		roleChangeEventParam.setRoleVos(Arrays.asList( roleDto.getRole().transToRoleVo()));
		roleChangeEventParam.setChangeType(ChangeType.MODIFY);
		AfsEventHelper.publishEvent(EventType.DURABLE, AfsRoleChangeEventTrigger.class,roleChangeEventParam,true);
		sysUserRoleService.remove(Wrappers.<SysUserRole>lambdaUpdate().eq(SysUserRole::getRoleId,roleDto.getRole().getId()).ne(SysUserRole::getUserId, SecurityUtils.getUser().getId()));
		List<SysUserRole> list = roleDto.getUserIds().stream().filter(userID-> !SecurityUtils.getUser().getId().equals(userID)).map(userId->{
			SysUserRole sysUserRole = new SysUserRole();
			sysUserRole.setUserId(userId);
			sysUserRole.setRoleId(roleDto.getRole().getId());
			return sysUserRole;
		}).collect(Collectors.toList());
		if(list.size()>0) {
			sysUserRoleService.saveBatch(list);
		}
		return new IResponse<SysRole>().setData(roleDto.getRole());
	}

	@RequestMapping(value = "/delAllByIds/{ids}", method = RequestMethod.DELETE)
	@ApiOperation(value = "批量通过ids删除")
	@SysLog("批量通过ids删除角色")
	@Transactional(rollbackFor = Exception.class)
	@CacheEvict(value = CommonConstants.USER_CACHE_KEY_PREFIX, allEntries = true)
	public IResponse<Boolean> delByIds(@PathVariable String[] ids) {
		List<Long> longIds = Arrays.asList(ids).stream().map(Long::parseLong).collect(Collectors.toList());
		List<RoleVo> sysRoles = sysRoleService.listByIds(longIds).stream().map(sysRole -> {
			RoleVo roleVo = sysRole.transToRoleVo();
			roleVo.setDelFlag(CommonConstants.STATUS_DEL);
			return  roleVo;
		}).collect(Collectors.toList());
		sysRoleService.deleteByRoleIds(longIds);
		RoleChangeEventParam roleChangeEventParam = new RoleChangeEventParam();
		roleChangeEventParam.setRoleVos(sysRoles);
		roleChangeEventParam.setChangeType(ChangeType.MODIFY);
		AfsEventHelper.publishEvent(EventType.DURABLE, AfsRoleChangeEventTrigger.class,roleChangeEventParam,true);
		return new IResponse<Boolean>().setData(true).setMsg("批量通过id删除数据成功");
	}

}
